package org.kiwi.util;

import org.apache.commons.lang3.StringUtils;
import org.kiwi.util.log.support.EnhancedLoggerFactory;
import org.slf4j.Logger;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 全局唯一序列生成器
 *
 * @email jack.liu.19910921@gmail.com
 * Created by jack on 17/6/27.
 */
public class SeqGenerator {

    private static final Logger LOGGER = EnhancedLoggerFactory.getLogger(SeqGenerator.class);

    private static final int DEFAULT_HASH_LENGTH = 3;

    private static final int DEFAULT_SEQ_LENGTH = 3;

    private static final SimpleDateFormat DEFAULT_TIME_FORMATTER = new SimpleDateFormat("yyyyMMddHHmmss");

    private static AtomicInteger atomicInteger = new AtomicInteger(0);

    public static String generatorSequence() {
        return generatorSequence(DEFAULT_HASH_LENGTH, DEFAULT_SEQ_LENGTH);
    }

    public static String generatorSequence(int seqLength) {
        return generatorSequence(DEFAULT_HASH_LENGTH, seqLength);
    }

    private static String generatorSequence(int hashLength, int seqLength) {
        String hashSeq = getInstanceHash(hashLength);
        String timeSeq = DEFAULT_TIME_FORMATTER.format(new Date());
        String seq = getSequence(seqLength);
        return hashSeq + timeSeq + seq;
    }

    private static String getInstanceHash(int hashLength) {
        String ipAddress = IPUtil.getLocalIP();
        int res = 0;
        try {
            for (String str : ipAddress.split("\\.")) {
                res += Integer.valueOf(str);
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        if (hashLength > 3) {
            int times = (int) Math.pow(10, hashLength);
            res += Math.abs(ipAddress.hashCode()) % times;
        }
        return StringUtils.rightPad(String.valueOf(res), hashLength, "0");
    }

    private static String getSequence(int length) {
        int times = (int) Math.pow(10, length);
        int res = atomicInteger.incrementAndGet() % times;
        return StringUtils.leftPad(String.valueOf(res), length, "0");
    }

    public static String generatorSeqNoUUID32() {
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }

}
